package com.yenlien.traceyun.plant.service;

import com.yenlien.traceyun.plant.dao.*;
import com.yenlien.traceyun.plant.entity.*;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.yenlien.traceyun.plant.utils.Tools.DATE_TIME_FORMATTER;

@Service
public class YenlienService {

    @Autowired
    private YenlienBannerDao yenlienBannerDao;
    @Autowired
    private YenlienProjectExampleDao yenlienProjectExampleDao;
    @Autowired
    private YenlienProductDao yenlienProductDao;
    @Autowired
    private YenlienNewsDao yenlienNewsDao;
    @Autowired
    private YenlienDao yenlienDao;
    @Autowired
    private YenlienSolutionDao yenlienSolutionDao;


    public YenlienBanner saveBanner(YenlienBanner yenlienBanner) {
        if (StringUtils.isBlank(yenlienBanner.getId())) {
            yenlienBanner.setState("1");
            yenlienBanner.setCreateTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
        }
        // 禁用同类型
//        if("1".equals(yenlienBanner.getState())){
//            YenlienBanner banner = yenlienBannerDao.findByTypeAndState(yenlienBanner.getType(), "1");
//            if(banner != null && !banner.getId().equals(yenlienBanner.getId())){
//                banner.setState("2");
//                yenlienBannerDao.save(banner);
//            }
//        }
        // 保留一个同类型启用状态
        if("2".equals(yenlienBanner.getState())){
            YenlienBanner banner = yenlienBannerDao.findByTypeAndState(yenlienBanner.getType(), "1");
            if(banner == null){
                throw new BusinessException("同类型Bannner须保留一个启用状态");
            }
        }
        return yenlienBannerDao.save(yenlienBanner);
    }

    public YenlienProjectExample saveProjectExample(YenlienProjectExample yenlienProjectExample) {
        if (StringUtils.isBlank(yenlienProjectExample.getId())) {
            yenlienProjectExample.setState("1");
            yenlienProjectExample.setCreateTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
        }
        return yenlienProjectExampleDao.save(yenlienProjectExample);
    }

    public YenlienProduct saveProduct(YenlienProduct yenlienProduct) {
        if (StringUtils.isBlank(yenlienProduct.getId())) {
            yenlienProduct.setState("1");
            yenlienProduct.setCreateTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
        }
        return yenlienProductDao.save(yenlienProduct);
    }

    public YenlienNews saveNews(YenlienNews yenlienNews) {
        if (StringUtils.isBlank(yenlienNews.getId())) {
            yenlienNews.setState("2");
            yenlienNews.setCreateTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
        }
        return yenlienNewsDao.save(yenlienNews);
    }

    public YenlienSolution saveSolution(YenlienSolution yenlienSolution) {
        if (StringUtils.isBlank(yenlienSolution.getId())) {
            yenlienSolution.setState("1");
            yenlienSolution.setCreateTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
        }
        return yenlienSolutionDao.save(yenlienSolution);
    }

    public Yenlien saveInfo(Yenlien yenlien) {
        if (StringUtils.isBlank(yenlien.getId())) {
            yenlien.setCreateTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
        }
        return yenlienDao.save(yenlien);
    }







    public Page<YenlienBanner> findBanner(YenlienBanner yenlienBanner) {
        Pageable pageable = PageRequest.of(yenlienBanner.getPage(), yenlienBanner.getPageSize(), Sort.Direction.DESC, ("createTime"));
        return yenlienBannerDao.findAll((Root<YenlienBanner> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genBannerPredicate(yenlienBanner, root, cb);
        }, pageable);
    }

    public List<YenlienBanner> findBannerList(YenlienBanner yenlienBanner) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        return yenlienBannerDao.findAll((Root<YenlienBanner> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genBannerPredicate(yenlienBanner, root, cb);
        }, sort);
    }
    public Predicate genBannerPredicate(YenlienBanner yenlienBanner, Root<YenlienBanner> root, CriteriaBuilder cb){
        List<Predicate> list = new ArrayList<>();
        if(StringUtils.isNotBlank(yenlienBanner.getType()))
            list.add(cb.equal(root.get("type"), yenlienBanner.getType()));
        if(StringUtils.isNotBlank(yenlienBanner.getName()))
            list.add(cb.like(root.get("name"), "%" + yenlienBanner.getName() + "%"));
        if(StringUtils.isNotBlank(yenlienBanner.getState()))
            list.add(cb.equal(root.get("state"), yenlienBanner.getState()));
        return cb.and(list.toArray(new Predicate[list.size()]));
    }



    public YenlienBanner findBannerById(String id) {
        return yenlienBannerDao.findById(id).orElseThrow(() -> new BusinessException("该Banner不存在"));
    }
    public void delBannerById(String id) {
        yenlienBannerDao.deleteById(id);
    }


    public Page<YenlienProjectExample> findProjectExamplePage(YenlienProjectExample yenlienProjectExample) {
        Pageable pageable = PageRequest.of(yenlienProjectExample.getPage(), yenlienProjectExample.getPageSize(), Sort.Direction.DESC, ("createTime"));
        return yenlienProjectExampleDao.findAll((Root<YenlienProjectExample> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genProjectExamplePredicate(yenlienProjectExample, root, cb);
        }, pageable);
    }

    public List<YenlienProjectExample> findProjectExampleList(YenlienProjectExample yenlienProjectExample) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        return yenlienProjectExampleDao.findAll((Root<YenlienProjectExample> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genProjectExamplePredicate(yenlienProjectExample, root, cb);
        }, sort);
    }
    public YenlienProjectExample findProjectExampleById(String id) {
        return yenlienProjectExampleDao.findById(id).orElseThrow(() -> new BusinessException("该项目案例不存在"));
    }
    public void delProjectExampleById(String id) {
        yenlienProjectExampleDao.deleteById(id);
    }

    public Predicate genProjectExamplePredicate(YenlienProjectExample yenlienProjectExample, Root<YenlienProjectExample> root, CriteriaBuilder cb){
        List<Predicate> list = new ArrayList<>();
        if(StringUtils.isNotBlank(yenlienProjectExample.getName()))
            list.add(cb.like(root.get("name"), "%" + yenlienProjectExample.getName() + "%"));
        if(StringUtils.isNotBlank(yenlienProjectExample.getState()))
            list.add(cb.equal(root.get("state"), yenlienProjectExample.getState()));
        return cb.and(list.toArray(new Predicate[list.size()]));
    }


    public Page<YenlienProduct> findProductPage(YenlienProduct yenlienProduct) {
        Pageable pageable = PageRequest.of(yenlienProduct.getPage(), yenlienProduct.getPageSize(), Sort.Direction.DESC, ("createTime"));
        return yenlienProductDao.findAll((Root<YenlienProduct> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genProductPredicate(yenlienProduct, root, cb);
        }, pageable);
    }

    public List<YenlienProduct> findProductList(YenlienProduct yenlienProduct) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        return yenlienProductDao.findAll((Root<YenlienProduct> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genProductPredicate(yenlienProduct, root, cb);
        }, sort);
    }
    public YenlienProduct findProductById(String id) {
        return yenlienProductDao.findById(id).orElseThrow(() -> new BusinessException("该产品服务不存在"));
    }
    public void delProductById(String id) {
        yenlienProductDao.deleteById(id);
    }

    public Predicate genProductPredicate(YenlienProduct yenlienProduct, Root<YenlienProduct> root, CriteriaBuilder cb){
        List<Predicate> list = new ArrayList<>();
        if(StringUtils.isNotBlank(yenlienProduct.getName()))
            list.add(cb.like(root.get("name"), "%" + yenlienProduct.getName() + "%"));
        if(yenlienProduct.getHomeShow() != null)
            list.add(cb.equal(root.get("homeShow"), yenlienProduct.getHomeShow()));
        if(StringUtils.isNotBlank(yenlienProduct.getState()))
            list.add(cb.equal(root.get("state"), yenlienProduct.getState()));
        return cb.and(list.toArray(new Predicate[list.size()]));
    }


    public Page<YenlienSolution> findSolutionPage(YenlienSolution yenlienSolution) {
        Pageable pageable = PageRequest.of(yenlienSolution.getPage(), yenlienSolution.getPageSize(), Sort.Direction.DESC, ("createTime"));
        return yenlienSolutionDao.findAll((Root<YenlienSolution> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genSolutionPredicate(yenlienSolution, root, cb);
        }, pageable);
    }

    public List<YenlienSolution> findSolutionList(YenlienSolution yenlienProduct) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        return yenlienSolutionDao.findAll((Root<YenlienSolution> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genSolutionPredicate(yenlienProduct, root, cb);
        }, sort);
    }

    public YenlienSolution findSolutionById(String id) {
        return yenlienSolutionDao.findById(id).orElseThrow(() -> new BusinessException("该解决方案不存在"));
    }
    public void delSolutionById(String id) {
        yenlienSolutionDao.deleteById(id);
    }

    public Predicate genSolutionPredicate(YenlienSolution yenlienSolution, Root<YenlienSolution> root, CriteriaBuilder cb){
        List<Predicate> list = new ArrayList<>();
        if(StringUtils.isNotBlank(yenlienSolution.getName()))
            list.add(cb.like(root.get("name"), "%" + yenlienSolution.getName() + "%"));
        if(StringUtils.isNotBlank(yenlienSolution.getPlanName()))
            list.add(cb.like(root.get("planName"), "%" + yenlienSolution.getPlanName() + "%"));
        if(StringUtils.isNotBlank(yenlienSolution.getState()))
            list.add(cb.equal(root.get("state"), yenlienSolution.getState()));
        return cb.and(list.toArray(new Predicate[list.size()]));
    }


    public Page<YenlienNews> findNewsPage(YenlienNews yenlienNews) {
        Pageable pageable = PageRequest.of(yenlienNews.getPage(), yenlienNews.getPageSize(), Sort.Direction.DESC, ("createTime"));
        return yenlienNewsDao.findAll((Root<YenlienNews> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genNewsPredicate(yenlienNews, root, cb);
        }, pageable);
    }

    public List<YenlienNews> findNewsList(YenlienNews yenlienNews) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        return yenlienNewsDao.findAll((Root<YenlienNews> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genNewsPredicate(yenlienNews, root, cb);
        }, sort);
    }

    public Predicate genNewsPredicate(YenlienNews yenlienNews, Root<YenlienNews> root, CriteriaBuilder cb){
        List<Predicate> list = new ArrayList<>();
        if(StringUtils.isNotBlank(yenlienNews.getName()))
            list.add(cb.like(root.get("name"), "%" + yenlienNews.getName() + "%"));
        if(StringUtils.isNotBlank(yenlienNews.getPublisher()))
            list.add(cb.like(root.get("publisher"), "%" + yenlienNews.getPublisher() + "%"));
        if(yenlienNews.getHomeShow() != null)
            list.add(cb.equal(root.get("homeShow"), yenlienNews.getHomeShow()));
        if(StringUtils.isNotBlank(yenlienNews.getState()))
            list.add(cb.equal(root.get("state"), yenlienNews.getState()));
        if(StringUtils.isNotBlank(yenlienNews.getType()))
            list.add(cb.equal(root.get("type"), yenlienNews.getType()));
        return cb.and(list.toArray(new Predicate[list.size()]));
    }

    public YenlienNews findNewsById(String id) {
        YenlienNews news = yenlienNewsDao.findById(id).orElseThrow(() -> new BusinessException("该新闻资讯不存在"));
        Integer clickNum = news.getClickNum() == null ? 1 : news.getClickNum();
        clickNum += 1;
        news.setClickNum(clickNum);
        yenlienNewsDao.save(news);
        return news;
    }
    public void delNewsById(String id) {
        yenlienNewsDao.deleteById(id);
    }
    public YenlienNews setNewsState(String id, String state) {
        YenlienNews news = yenlienNewsDao.findById(id).orElseThrow(() -> new BusinessException("该新闻资讯不存在"));
        if("1".equals(state))
            news.setPublishTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
        news.setState(state);
        return yenlienNewsDao.save(news);
    }


    public Yenlien findYenlien() {
        return yenlienDao.findAll().get(0);
    }




    public List<String> findProdType() {
        return yenlienProductDao.findProdType();
    }




















}
